package com.twu.biblioteca.dao.memory;

import com.google.common.collect.Lists;
import com.google.inject.Singleton;

import com.twu.biblioteca.dao.BookDao;
import com.twu.biblioteca.entity.Book;
import com.twu.biblioteca.exception.DaoNotFoundException;
import com.twu.biblioteca.util.Predicate;

import java.util.List;

@Singleton
public class MemoryBookDao extends MemoryBaseDao<Book> implements BookDao {

  public MemoryBookDao() {
    List<Book> booksInBiblioteca = Lists.newArrayList(
        new Book(8941230131L, "Pride and Prejudice", "Jane Austen"),
        new Book(8941230132L, "1984", "George Orwell"),
        new Book(8941230133L, "Animal Farm", "George Orwell"),
        new Book(8941230134L, "The Hobbit", "J.R.R. Tolkien"),
        new Book(8941230135L, "Lord of the Rings", "J.R.R. Tolkien"));

    super.setItemList(booksInBiblioteca);
  }

  public Book findByTitle(String title) {
    return memoryBookDaoTemplate(new Predicate<Book, String>() {
      public boolean isTrue(Book book, String title) {
        return book.getTitle().equals(title);
      }
    }, title);
  }

  public Book findByIsbn(long isbn) {
    return memoryBookDaoTemplate(new Predicate<Book, Long>() {
      public boolean isTrue(Book book, Long isbn) {
        return book.getIsbn() == isbn;
      }
    }, isbn);
  }

  public List<Book> getAvailableBooks() {
    List<Book> availableBooks = Lists.newArrayList();
    for (Book b : itemList) {
      if(b.isAvailable()) availableBooks.add(b.getBook(b));
    }
    return availableBooks;
  }

  public List<Book> getCheckoutBooks() {
    List<Book> checkoutBooks = Lists.newArrayList();
    for (Book b : itemList) {
      if(!b.isAvailable()) checkoutBooks.add(b.getBook(b));
    }
    return checkoutBooks;
  }

  private Book memoryBookDaoTemplate(Predicate predicate, Object obj) {
    for (Book b : itemList) {
      if(predicate.isTrue(b, obj)) return b;
    }
    throw new DaoNotFoundException("No book found with the given ID");
  }

}
